using System;
using System.Collections.Generic;
using System.Text;
using CI.Organism;

namespace CI.Interfaces
{
    /// <summary>
    /// Cell Interface, primary building block eg, Neural, Body part as well as supporting debugging
    /// </summary>
    public interface ICell
    {
        /// <summary>Add a cell to its environment</summary>
        void AddCell();
        /// <summary>Delete a cell from its environment</summary>
        void DelCell();

        // todo : consider making this only 32 to be compatablie with db's easier
        /// <summary>Heart beat Time Stamp of when the cell is Alive(Created)</summary>
        UInt32 HBTSAlive
        {
            get;
        }

        // todo : consider making this only 32 to be compatablie with db's easier
        /// <summary>Heart beat Time Stamp of when the cell is Dead(Destroyed)</summary>
        UInt32 HBTSDead
        {
            get;
        }

        /// <summary>Organism the cell belongs to</summary>
        IOrganism Organism
        {
            get;
            set;
        }

        /// <summary>Cell's GUID used to uniquely identify it in the Organism</summary>
        Guid Guid
        {
            get;
            set;
        }

        /// <summary>Is the cell active(alive)</summary>
        bool Active { get;set;}

        // <summary>State change Debug notifier</summary>
        //delegate StateChangeDebug;

        /// <summary>
        /// Take this parent cell and create a new cell to be put in the new child Organism
        /// Mutate the current cell and return a new one, deep class level mutation
        /// </summary>
        /// <param name="mutationRate">mutation rate to be applied</param>
        /// <param name="childOrganism">child child Organism it will be going into</param>
        /// <returns>new cell for child</returns>
        ICell Mutate(double mutationRate, IOrganism childOrganism);

        /// <summary>
        /// do a equals comparison of one cell type to another only comparing the value types, no refference comparisons
        /// </summary>
        /// <param name="cell">cell to compare against</param>
        /// <returns>true if equal value types</returns>
        bool EqualsValueTypes(ICell cell);

        /// <summary>
        /// To String extended
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        string ToString(string value);
    }
    
    /// <summary>
    /// Reproductive cell type which can reproduce the childOrganism
    /// </summary>
    public interface IReproductive : ICell { }

    /// <summary>
    /// All the cells
    /// </summary>
    public interface ICellCollection : IList<ICell>
    {
        /// <summary>
        /// Take this parent cell collection and create a new cell collection to be put in the new child Organism
        /// Mutate the current cells and return a new one, deep class level mutation
        /// </summary>
        /// <param name="mutationRate">mutation rate to be applied</param>
        /// <param name="childOrganism">child Organism it will be going into</param>
        /// <returns>new cell collection for child</returns>
        ICellCollection Mutate(double mutationRate, IOrganism childOrganism);

        /// <summary>
        /// Find the cell with the specifed guid
        /// </summary>
        /// <param name="guid">guid to find</param>
        /// <returns>Cell</returns>
        ICell Find(Guid guid);

        /// <summary>
        /// Find the cell with the specifed guid as a string
        /// </summary>
        /// <param name="guid">guid to find as a string</param>
        /// <returns>Cell</returns>
        ICell Find(string guid);

        /// <summary>
        /// Find the base physical cell that everything is build off
        /// </summary>
        /// <returns>Cell</returns>
        ICell FindPhysicalZygote();

        /// <summary>
        /// this will scan all the cells and find neurons
        /// </summary>
        /// <returns></returns>
        INeuronCollection Neurons();

        /// <summary>
        /// do a equals comparison of one cell collection type to another only comparing the value types, no refference comparisons
        /// </summary>
        /// <param name="cells">cells to compare against</param>
        /// <returns>true if equal value types</returns>
        bool EqualsValueTypes(ICellCollection cells);
    }
}
